package cn.cucc.utils;

import java.util.ArrayList;
import java.util.Collection;
import java.util.List;

import javax.persistence.criteria.CriteriaBuilder;
import javax.persistence.criteria.Predicate;
import javax.persistence.criteria.Root;

/**
 * 查询语句生成器
 * 
 * @author CYM
 *
 */
public abstract class ConditionWrapper {
	boolean andLink;

	List<Object> list = new ArrayList<Object>();

	public Predicate toPredicates(CriteriaBuilder criteriaBuilder, Root root) {
		Predicate finalPredicate = null;
		if (list.size() > 0) {
			List<Predicate> blocks = new ArrayList<Predicate>();
			for (Object object : list) {
				if (object instanceof Condition) {
					Condition condition = (Condition) object;

					Predicate predicate = null;

					if (condition.getValue() == null) {
						if (condition.getOperation().equals("IS NULL")) {
							predicate = criteriaBuilder.isNull(root.get(condition.getColumn()));
						} else if (condition.getOperation().equals("IS NOT NULL")) {
							predicate = criteriaBuilder.isNotNull(root.get(condition.getColumn()));
						}
					} else {
						if (condition.getOperation().equals("=")) {
							predicate = criteriaBuilder.equal(root.get(condition.getColumn()), condition.getValue());
						} else if (condition.getOperation().equals("<>")) {
							predicate = criteriaBuilder.notEqual(root.get(condition.getColumn()), condition.getValue());
						} else if (condition.getOperation().equals("<")) {
							predicate = criteriaBuilder.lessThan(root.get(condition.getColumn()), (Comparable) condition.getValue());
						} else if (condition.getOperation().equals("<=")) {
							predicate = criteriaBuilder.lessThanOrEqualTo(root.get(condition.getColumn()), (Comparable) condition.getValue());
						} else if (condition.getOperation().equals(">")) {
							predicate = criteriaBuilder.greaterThan(root.get(condition.getColumn()), (Comparable) condition.getValue());
						} else if (condition.getOperation().equals(">=")) {
							predicate = criteriaBuilder.greaterThanOrEqualTo(root.get(condition.getColumn()), (Comparable) condition.getValue());
						} else if (condition.getOperation().equals("LIKE")) {
							predicate = criteriaBuilder.like(root.get(condition.getColumn()), "%" + condition.getValue() + "%");
						} else if (condition.getOperation().equals("IN")) {
							CriteriaBuilder.In in = criteriaBuilder.in(root.get(condition.getColumn()));
							for (Object obj : (Collection<?>) condition.getValue()) {
								in.value(obj);
							}
							predicate = in;
						} else if (condition.getOperation().equals("NOT IN")) {
							CriteriaBuilder.In in = criteriaBuilder.in(root.get(condition.getColumn()));
							for (Object obj : (Collection<?>) condition.getValue()) {
								in.value(obj);
							}
							predicate = criteriaBuilder.not(in);
						}

					}
					blocks.add(predicate);
				}

				if (object instanceof ConditionWrapper) {
					ConditionWrapper conditionWrapper = (ConditionWrapper) object;
					blocks.add(conditionWrapper.toPredicates(criteriaBuilder, root));
				}

			}

			if (andLink) {
				finalPredicate = criteriaBuilder.and(blocks.toArray(new Predicate[blocks.size()]));
			} else {
				finalPredicate = criteriaBuilder.or(blocks.toArray(new Predicate[blocks.size()]));
			}

		}

		return finalPredicate;
	}



	/**
	 * 等于
	 * 
	 * @param column 字段
	 * @param params 参数
	 * @return ConditionWrapper
	 */
	public ConditionWrapper eq(String column, Object params) {
		list.add(new Condition(column, "=", params));
		return this;
	}

	/**
	 * 不等于
	 * 
	 * @param column 字段
	 * @param params 参数
	 * @return ConditionWrapper
	 */
	public ConditionWrapper ne(String column, Object params) {
		list.add(new Condition(column, "<>", params));
		return this;
	}

	/**
	 * 小于
	 * 
	 * @param column 字段
	 * @param params 参数
	 * @return ConditionWrapper
	 */
	public ConditionWrapper lt(String column, Object params) {
		list.add(new Condition(column, "<", params));
		return this;
	}

	/**
	 * 小于或等于
	 * 
	 * @param column 字段
	 * @param params 参数
	 * @return ConditionWrapper
	 */
	public ConditionWrapper lte(String column, Object params) {
		list.add(new Condition(column, "<=", params));
		return this;
	}

	/**
	 * 大于
	 * 
	 * @param column 字段
	 * @param params 参数
	 * @return ConditionWrapper
	 */
	public ConditionWrapper gt(String column, Object params) {
		list.add(new Condition(column, ">", params));
		return this;
	}

	/**
	 * 大于或等于
	 * 
	 * @param column 字段
	 * @param params 参数
	 * @return ConditionWrapper
	 */
	public ConditionWrapper gte(String column, Object params) {
		list.add(new Condition(column, ">=", params));
		return this;
	}

	/**
	 * 相似于
	 * 
	 * @param column 字段
	 * @param params 参数
	 * @return ConditionWrapper
	 */
	public ConditionWrapper like(String column, String params) {
		list.add(new Condition(column, "LIKE", "%" + params + "%"));
		return this;
	}

	/**
	 * 在其中
	 * 
	 * @param column 字段
	 * @param params 参数
	 * @return ConditionWrapper
	 */
	public ConditionWrapper in(String column, Collection<?> params) {
		list.add(new Condition(column, "IN", params));
		return this;
	}

	/**
	 * 不在其中
	 * 
	 * @param column 字段
	 * @param params 参数
	 * @return ConditionWrapper
	 */
	public ConditionWrapper nin(String column, Collection<?> params) {
		list.add(new Condition(column, "NOT IN", params));
		return this;
	}

	/**
	 * 为空
	 * 
	 * @param <T>
	 * 
	 * @param column 字段
	 * @return ConditionWrapper
	 */
	public ConditionWrapper isNull(String column) {
		list.add(new Condition(column, "IS NULL", null));
		return this;
	}

	/**
	 * 不为空
	 * 
	 * @param <T>
	 * 
	 * @param column 字段
	 * @return ConditionWrapper
	 */
	public ConditionWrapper isNotNull(String column) {
		list.add(new Condition(column, "IS NOT NULL", null));
		return this;
	}

	public boolean notEmpty() {
		return list.size() > 0;
	}

}
